﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.Common.Exceptions.FaultContracts;
using System.ServiceModel;

namespace Sinacor.Infra.Common.Exceptions
{
    /// <summary>
    /// Exceção disparada para erros de negócio
    /// </summary>
    public class BusinessException : BaseErrorNumberException
    {
        /// <summary>
        /// Construtor que inicializa ErrorNumber
        /// </summary>
        /// <param name="errorNumber">Número do erro</param>
        /// <param name="parameters">Parâmetros para a mensagem de erro</param>
        public BusinessException(int errorNumber, params object[] parameters)
            : this(errorNumber, null, null, parameters)
        {
        }

        /// <summary>
        /// Construtor que inicializa ErrorNumber e InnerException
        /// </summary>
        /// <param name="errorNumber">Número do erro</param>
        /// <param name="innerException">Erro que originou a Exception</param>
        /// <param name="parameters">Parâmetros para a mensagem de erro</param>
        public BusinessException(int errorNumber, Exception innerException, params object[] parameters)
            : this(errorNumber, null, innerException, parameters)
        {
        }

        /// <summary>
        /// Construtor que inicializa ErrorNumber, Message e InnerException
        /// </summary>
        /// <param name="errorNumber">Número do erro</param>
        /// <param name="message">Mensagem de erro</param>
        /// <param name="innerException">Erro que originou a Exception</param>
        /// <param name="parameters">Parâmetros para a mensagem de erro</param>
        public BusinessException(int errorNumber, string message, Exception innerException, params object[] parameters)
            : base(errorNumber, message, innerException)
        {
            _parameters = parameters.ToList();            
        }

        private List<object> _parameters;
        /// <summary>
        /// Parâmetros para a mensagem de erro
        /// </summary>
        public List<object> Parameters
        {
            get { return _parameters; }
        }

        /// <summary>
        /// Cria instância da falta
        /// </summary>
        /// <returns>Instância da falta</returns>
        protected override BaseFault CreateFaultInstance()
        {
            return new BusinessFault();
        }

        /// <summary>
        /// Cria uma falta a partir da exceção
        /// </summary>
        /// <returns>Falta com o erro</returns>
        public override BaseFault CreateFault()
        {
            BusinessFault fault = (BusinessFault)base.CreateFault();

            fault.Parameters.AddRange(this.Parameters);

            return fault;
        }

        /// <summary>
        /// Cria uma exceção de falta a partir da exceção
        /// </summary>
        /// <returns>Falta com o erro</returns>
        public override FaultException CreateFaultException()
        {
            return new FaultException<BusinessFault>((BusinessFault)this.CreateFault(), this.Message);
        }
    }
}
